#!/usr/bin/python3
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t -*-

import os
import sys
import glob
import hashlib


class Main:

    @staticmethod
    def get_destination_file_list():
        return ["wolfanoz-256gb.idx", "wolfanoz-512gb.idx", "wolfanoz-1tb.idx", "wolfanoz-3tb.idx"]

    def __init__(self, srcDir, dstFile):
        self.srcDir = srcDir
        self.dstFile = dstFile

    def run(self):
        print("Scanning directory \"%s\"." % (self.srcDir))
        fullfnList = glob.glob(os.path.join(srcDir, "LaunchBox", "Games", "**"), recursive=True)

        dstData = []
        for fullfn in fullfnList:
            if os.path.isdir(fullfn):
                continue
            print("Processing \"%s\"." % (fullfn))
            filehash = Util.generate_sha256(fullfn)
            filesize = os.path.getsize(fullfn)
            filename = fullfn[len(srcDir)+1:]
            dstData.append((filehash, filesize, filename))

        print("Total files: %d" % (len(dstData)))

        totalSize = sum([x[1] for x in dstData])
        print("Total size: %s (%d bytes)" % (Util.format_size(totalSize), totalSize))

        print("Writing to \"%s\"." % (self.dstFile))
        with open(self.dstFile, "w") as f:
            max0 = max([len(x[0]) for x in dstData])
            max1 = max([len(str(x[1])) for x in dstData])
            formatStr = "%%-%ds %%-%ds %%s" % (max0, max1)
            print(formatStr % ("# hash", "# size", "# filepath"), file=f)
            for filehash, filesize, filename in dstData:
                print(formatStr % (filehash, str(filesize), filename), file=f)

        print("Done.")


class Util:

    @staticmethod
    def generate_sha256(file):
        sha256 = hashlib.sha256()
        with open(file, 'rb') as f:
            while True:
                data = f.read(65536)
                if not data:
                    break
                sha256.update(data)
        return sha256.hexdigest()

    @staticmethod
    def format_size(value):
        # value is in bytes
        if value > 1024 * 1024 * 1024 * 1024:
            return "%.1fTB" % (value / 1024 / 1024 / 1024 / 1024)
        elif value > 1024 * 1024 * 1024:
            return "%.1fGB" % (value / 1024 / 1024 / 1024)
        elif value > 1024 * 1024:
            return "%.1fMB" % (value / 1024 / 1024)
        elif value > 1024:
            return "%.1fKB" % (value / 1024)
        else:
            assert False


if len(sys.argv) < 2:
    print("Usage: generate-hash-list.py <source-directory> <destination-file>.")
    sys.exit(1)

srcDir = sys.argv[1]
if not os.path.isabs(srcDir):
    print("Usage: <source-directory> must be an absolute path.")
    sys.exit(1)
if not os.path.isdir(srcDir):
    print("Usage: <source-directory> is not a directory.")
    sys.exit(1)

dstFile = sys.argv[2]
if os.path.basename(dstFile) not in Main.get_destination_file_list():
    print("Usage: <destination-file> must have a name in the range of %s or %s." % (",".join(Main.get_destination_file_list()[:-1]), Main.get_destination_file_list()[-1]))
    sys.exit(1)

Main(srcDir, dstFile).run()
